package com.perfma.xtest;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author: junhui.si
 * @date: 2021-10-08 17:46
 **/
public class JmeterTest {
    public static void main(String[] args) throws Exception {
        String content = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<jmeterTestPlan version=\"1.2\" properties=\"5.0\" jmeter=\"5.4\">\n" +
                "  <hashTree>\n" +
                "    <TestPlan guiclass=\"TestPlanGui\" testclass=\"TestPlan\" testname=\"测试计划\" enabled=\"true\">\n" +
                "      <stringProp name=\"TestPlan.comments\"/>\n" +
                "      <boolProp name=\"TestPlan.functional_mode\">false</boolProp>\n" +
                "      <boolProp name=\"TestPlan.tearDown_on_shutdown\">true</boolProp>\n" +
                "      <boolProp name=\"TestPlan.serialize_threadgroups\">false</boolProp>\n" +
                "      <elementProp name=\"TestPlan.user_defined_variables\" elementType=\"Arguments\" guiclass=\"ArgumentsPanel\" testclass=\"Arguments\" testname=\"用户定义的变量\" enabled=\"true\">\n" +
                "        <collectionProp name=\"Arguments.arguments\"/>\n" +
                "      </elementProp>\n" +
                "      <stringProp name=\"TestPlan.user_define_classpath\"/>\n" +
                "    </TestPlan>\n" +
                "    <hashTree>\n" +
                "      <ThreadGroup guiclass=\"ThreadGroupGui\" testclass=\"ThreadGroup\" testname=\"1111\" enabled=\"true\">\n" +
                "        <stringProp name=\"ThreadGroup.on_sample_error\">continue</stringProp>\n" +
                "        <elementProp name=\"ThreadGroup.main_controller\" elementType=\"LoopController\" guiclass=\"LoopControlPanel\" testclass=\"LoopController\" testname=\"循环控制器\" enabled=\"true\">\n" +
                "          <boolProp name=\"LoopController.continue_forever\">false</boolProp>\n" +
                "          <stringProp name=\"LoopController.loops\">1</stringProp>\n" +
                "        </elementProp>\n" +
                "        <stringProp name=\"ThreadGroup.num_threads\">1</stringProp>\n" +
                "        <stringProp name=\"ThreadGroup.ramp_time\">1</stringProp>\n" +
                "        <boolProp name=\"ThreadGroup.scheduler\">false</boolProp>\n" +
                "        <stringProp name=\"ThreadGroup.duration\"/>\n" +
                "        <stringProp name=\"ThreadGroup.delay\"/>\n" +
                "        <boolProp name=\"ThreadGroup.same_user_on_next_iteration\">true</boolProp>\n" +
                "      </ThreadGroup>\n" +
                "      <hashTree><CSVDataSet guiclass=\"TestBeanGUI\" testclass=\"CSVDataSet\" testname=\"CSV 数据文件设置\" enabled=\"true\">\n" +
                "          <stringProp name=\"delimiter\">,</stringProp>\n" +
                "          <stringProp name=\"fileEncoding\"/>\n" +
                "          <stringProp name=\"filename\">/Users/sijunhui/Downloads/qingsi工1厂.csv</stringProp>\n" +
                "          <boolProp name=\"ignoreFirstLine\">true</boolProp>\n" +
                "          <boolProp name=\"quotedData\">false</boolProp>\n" +
                "          <boolProp name=\"recycle\">true</boolProp>\n" +
                "          <stringProp name=\"shareMode\">shareMode.all</stringProp>\n" +
                "          <boolProp name=\"stopThread\">false</boolProp>\n" +
                "          <stringProp name=\"variableNames\">a1,a2</stringProp>\n" +
                "        </CSVDataSet><CSVDataSet guiclass=\"TestBeanGUI\" testclass=\"CSVDataSet\" testname=\"CSV 数据文件设置\" enabled=\"true\">\n" +
                "          <stringProp name=\"delimiter\">,</stringProp>\n" +
                "          <stringProp name=\"fileEncoding\"/>\n" +
                "          <stringProp name=\"filename\">/Users/sijunhui/Downloads/qingsi工厂.csv</stringProp>\n" +
                "          <boolProp name=\"ignoreFirstLine\">true</boolProp>\n" +
                "          <boolProp name=\"quotedData\">false</boolProp>\n" +
                "          <boolProp name=\"recycle\">true</boolProp>\n" +
                "          <stringProp name=\"shareMode\">shareMode.all</stringProp>\n" +
                "          <boolProp name=\"stopThread\">false</boolProp>\n" +
                "          <stringProp name=\"variableNames\">a2,a4</stringProp>\n" +
                "        </CSVDataSet><hashTree/></hashTree>\n" +
                "    </hashTree>\n" +
                "  </hashTree>\n" +
                "</jmeterTestPlan>";
        Map<String, List<String>> aa = getFileArgMap(content);
        System.out.println(aa);
    }

    /**
     * 解析csv节点中文件名和参数列表
     * key-csv文件名；value-参数列表
     *
     * @param content jmx内容
     * @return 结果
     * @throws Exception 异常
     */
    public static Map<String, List<String>> getFileArgMap(String content) throws Exception {
        Map<String, List<String>> resultMap = Maps.newHashMap();
        SAXReader reader = new SAXReader();
        Document document = reader.read(new ByteArrayInputStream(content.getBytes()));
        Element root = document.getRootElement();
        //查找所有csv设置
        List<Element> csvNodes = root.selectNodes("//*[contains(name(),'CSVDataSet')]");

        if (CollectionUtil.isEmpty(csvNodes)) {
            return resultMap;
        }

        for (Element csvNode : csvNodes) {
            // 分隔符
            Node delimiterNode = csvNode.selectSingleNode(".//*[@name='delimiter']");
            String delimiter = delimiterNode.getStringValue();
            // 参数
            Node argsNode = csvNode.selectSingleNode(".//*[@name='variableNames']");
            String args = argsNode.getStringValue();
            if (Strings.isNullOrEmpty(args)) {
                continue;
            }

            List<String> argList = Lists.newArrayList(args.split(delimiter));

            // 文件名
            Node filePathNode = csvNode.selectSingleNode(".//*[@name='filename']");
            String filePath = filePathNode.getStringValue();
            if (Strings.isNullOrEmpty(filePath)) {
                continue;
            }

            filePath = filePath.replace("\\", "/");
            String fileName = filePath.substring(filePath.lastIndexOf(File.separator) + 1);
            if (resultMap.containsKey(fileName)) {
                resultMap.get(fileName).addAll(argList);
                resultMap.put(fileName, resultMap.get(fileName).stream().distinct().collect(Collectors.toList()));
            } else {
                resultMap.put(fileName, argList.stream().distinct().collect(Collectors.toList()));
            }

        }
        return resultMap;
    }
}
